package service

import (
	"context"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"tFilm4/internal/model"
	"tFilm4/internal/model/entity"
	"tFilm4/internal/service/internal/dao"
	"tFilm4/internal/service/internal/do"
)

type sUser struct{}

var insUser = sUser{}

func User() *sUser {
	return &insUser
}

// SignUp  注册
func (s *sUser) SignUp(ctx context.Context, in model.SignUpInput) (err error) {
	return dao.User.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		insert, err := dao.UserProfile.Ctx(ctx).Data(do.UserProfile{
			Email: in.Email,
		}).Insert()
		if err != nil {
			return err
		}
		profileId, err := insert.LastInsertId()
		if err != nil {
			return err
		}
		_, err = dao.User.Ctx(ctx).Data(do.User{
			ProfileId: profileId,
			Username:  in.Username,
			Password:  in.Password,
		}).Insert()
		return err
	})
}

// CheckUsername 检查用户名可用性
func (s *sUser) CheckUsername(ctx context.Context, username string) error {
	count, err := dao.User.Ctx(ctx).Where(do.User{Username: username}).Count()
	if err != nil {
		return err
	}
	if count > 0 {
		return gerror.Newf(`用户名%s已存在`, username)
	}
	return nil
}

// QueryUserById  根据Id查询用户
func (s *sUser) QueryUserById(ctx context.Context, id string) (userInfo *model.UserInfo, err error) {
	userInfo = &model.UserInfo{
		User:        new(entity.User),
		UserProfile: new(entity.UserProfile),
	}
	err = dao.User.Ctx(ctx).Scan(&userInfo.User, "user_id", id)
	if err != nil {
		err = gerror.Newf(`用户编号%s不存在`, id)
		return
	}
	err = dao.UserProfile.Ctx(ctx).Scan(&userInfo.UserProfile, "profile_id", userInfo.User.ProfileId)
	return
}

// SignIn 用户登录
func (s *sUser) SignIn(ctx context.Context, username string, password string) (userInfo *model.UserInfo, err error) {
	userInfo = &model.UserInfo{
		User:        new(entity.User),
		UserProfile: new(entity.UserProfile),
	}
	err = dao.User.Ctx(ctx).Where(g.Map{
		dao.User.Columns().Username: username,
		dao.User.Columns().Password: password,
	}).Scan(&userInfo.User)
	if err != nil {
		err = gerror.New(`用户名或密码错误`)
		return
	}
	err = dao.UserProfile.Ctx(ctx).Scan(&userInfo.UserProfile, "profile_id", userInfo.User.ProfileId)

	return
}

func (s *sUser) GetUserList(ctx context.Context, in model.GetUserListInput) (count int, userInfos []model.UserInfo, err error) {
	err = dao.User.Ctx(ctx).WhereLike("user_id", "%"+in.SearchKey+"%").WhereOrLike("username", "%"+in.SearchKey+"%").Page(in.PageNum, in.PageSize).ScanList(&userInfos, "User")
	if err != nil {
		return
	}
	err = dao.UserProfile.Ctx(ctx).Where("profile_id", gdb.ListItemValuesUnique(&userInfos, "User", "UserId")).ScanList(&userInfos, "UserProfile", "User", "profile_id:ProfileId")
	if err != nil {
		return
	}
	count, err = dao.User.Ctx(ctx).Count()
	return
}

func (s *sUser) Update(ctx context.Context, in model.UpdateInput) (err error) {
	_, err = dao.User.Ctx(ctx).Update(g.Map{
		"username": in.Username,
	}, "user_id", in.UserId)
	return err
}
